﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.EntityClient;
using System.IO;
using System.Linq;

namespace zaklad_rtv
{
    public class DatabaseHelper
    {
        private DatabaseEntities _db;

        public DatabaseHelper()
        {
            Initialize();
        }

        private void Initialize()
        {
            var dbFileLocation = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, StringConstants.DBFile);
            var cstring = ConfigurationManager.ConnectionStrings["DatabaseEntities"].ConnectionString;
            var connectionStringBuilder = new EntityConnectionStringBuilder(cstring)
                {
                    ProviderConnectionString = String.Format("data source={0}", dbFileLocation)
                };
            _db = new DatabaseEntities(connectionStringBuilder.ToString());
            if (!File.Exists(StringConstants.DBFile))
            {
                var fileStream = File.Create(StringConstants.DBFile);
                fileStream.Close();
                _db.Database.ExecuteSqlCommand(StringConstants.ClientsCreateQuery);
                _db.Database.ExecuteSqlCommand(StringConstants.ServicesCreateQuery);
                _db.Database.ExecuteSqlCommand(StringConstants.ConfigCreateQuery);
                InsertConfigItems();
            }
        }

        private void InsertConfigItems()
        {
            var configFooter = new Config
                {
                    ConfigName = StringConstants.ConfigFooterName,
                    ConfigDescription = StringConstants.ConfigFooterDesc,
                    ConfigValue = ""
                };
            Save(configFooter);
        }

        public List<Client> GetAllClient()
        {
            return _db.Clients.ToList();
        }

        public List<Service> GetAllService()
        {
            return _db.Services.ToList();
        }

        public List<Config> GetAllConfig()
        {
            return _db.Configs.ToList();
        }

        public Client GetClient(long id)
        {
            return _db.Clients.FirstOrDefault(c => c.Id.Equals(id));
        }

        public Service GetService(long id)
        {
            return _db.Services.FirstOrDefault(s => s.Id.Equals(id));
        }

        public Config GetConfig(string name)
        {
            return _db.Configs.FirstOrDefault(c => c.ConfigName.Equals(name));
        }

        public void Save(Client client)
        {
            _db.Clients.Add(client);
            _db.SaveChanges();
        }

        public void Save(Service service)
        {
            _db.Services.Add(service);
            _db.SaveChanges();
        }

        public void Save(Config config)
        {
            _db.Configs.Add(config);
            _db.SaveChanges();
        }

        public void Delete(Client client)
        {
            foreach (var service in client.Services)
            {
                service.ClientId = -1;
            }
            _db.Clients.Remove(client);
            _db.SaveChanges();
        }

        public void Delete(Service service)
        {
            _db.Services.Remove(service);
            _db.SaveChanges();
        }

        public void Delete(Config config)
        {
            _db.Configs.Remove(config);
            _db.SaveChanges();
        }

        public bool Exists(Client client)
        {
            return _db.Clients.Contains(client);
        }

        public bool Exists(Service service)
        {
            return _db.Services.Contains(service);
        }

        public bool Exists(Config config)
        {
            return _db.Configs.Contains(config);
        }

        public void Update(Client client)
        {
            var clientFromDb = _db.Clients.FirstOrDefault(c => c.Id.Equals(client.Id));
            if (clientFromDb != null)
            {
                clientFromDb.FirstName = client.FirstName;
                clientFromDb.LastName = client.LastName;
                clientFromDb.Address = client.Address;
                clientFromDb.Telephone = client.Telephone;
                _db.SaveChanges();
            }
        }

        public void Update(Service service)
        {
            var serviceFromDb = _db.Services.FirstOrDefault(s => s.Id.Equals(service.Id));
            if (serviceFromDb != null)
            {
                serviceFromDb.Client = service.Client;
                serviceFromDb.BeginServiceDate = service.BeginServiceDate;
                serviceFromDb.ClientId = service.ClientId;
                serviceFromDb.Cost = service.Cost;
                serviceFromDb.DefectDescription = service.DefectDescription;
                serviceFromDb.EndServiceDate = service.EndServiceDate;
                serviceFromDb.HardwareType = service.HardwareType;
                serviceFromDb.Remarks = serviceFromDb.Remarks;
                serviceFromDb.ServiceDescription = service.ServiceDescription;
                _db.SaveChanges();
            }
        }

        public void Update(Config config)
        {
            var configFromDb = _db.Configs.FirstOrDefault(c => c.ConfigName.Equals(config.ConfigName));
            if (configFromDb != null)
            {
                configFromDb.ConfigValue = config.ConfigValue;
                _db.SaveChanges();
            }
        }

        public int GenerateServiceNumber()
        {
            long max = 0;
            if (_db.Services.Any())
                max = _db.Services.Max(s => s.Number);
            return (int)(max + 1);
        }
    }
}
